<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // 三种形式
      // 第一种  利用 =  赋值
      var user = {
        name: "john",
        age: 24,
      };
      var admin = user; // 引用地址的克隆
      // 但是 造成的后果就是 ,对其中一个进行操作,会影响到另外一个

      // 第二种情况
      // 浅拷贝/浅克隆  (只克隆对象的第一层属性)
      //需求: 想实现克隆出来的对象 操作时 不影响 原始对象 如何克隆
      var obj = {
        name: "张三",
        age: 23,
      };
      // var temp = user;///不行
      //需要创建一个空对象, 循环遍历原始对象,往空对象 里边逐一追加属性
      var temp = {};
      for (var key in obj) {
        temp[key] = obj[key];
      }
      console.log(temp); // {name: "张三", age: 23}  克隆成功
      temp.name = "李四";
      console.log("temp", temp);
      console.log("obj", obj);

      // Object.assign(目标对象,原始对象....)
      // 该方法将所有原始对象的属性拷贝到目标对象中
      var result = Object.assign({}, obj); // 对obj 的浅拷贝
      console.log("result", result);

      // 第三种情况
      // 需求: 想实现克隆出来的对象 操作时 不影响 原始对象.  如何克隆?
      // 如果原始对象嵌套层数太多怎么办?
      var person = {
        name: "小明",
        age: 30,
        child: {
          name: "小红",
          age: 3,
        },
      };
      // 对person 使用浅拷贝
      var p1 = Object.assign({}, person);
      console.log(p1);
      p1.name = "小王"; // 第一层属性修改 不会相互影响
      p1.child.age = 7; // 对于第二层属性 ,还是会互相影响
      //  person 的child 属性 保存的仅仅是 小红对象的 引用地址
      // 浅克隆 是循环遍历第一层属性,,把第一层属性的属性值(如果是对象,就是把地址给了目标对象的属性) 给了 目标对象
      console.log("p1", p1);
      console.log("person", person);

      // 深拷贝  要实现的就是 ,不管有多少层, 都不能相互影响
      // 要么借助 loadsh工具库 实现
      // 要么 自己遍历  组装  (递归)
      function deepClone(obj) {
        var res = {};
        for (var key in obj) {
          if (typeof obj[key] == "object") {
            // 对象
            // 接着遍历 person[key]
            res[key] = deepClone(obj[key]);
          } else {
            // 基本数据
            res[key] = obj[key];
          }
        }
        return res;
      }
      var p2 = deepClone(person);
      console.log(p2);
      p2.child.name = "john";
      console.log("p2", p2);
      console.log("person", person);
    </script>
  </body>
</html>
